﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary; 
using CriptoHash.Model;

namespace CriptoHash.Connection
{
    public class Cliente : Conector
    {
        public Cliente(string Ip, int Porta)
            : base(Ip, Porta)
        {

        }

        public override bool conectar()
        {
            if (DEBUG)
            {
                System.Diagnostics.Debug.WriteLine("# Tentando conectar servidor!");
            }
            if (Conectado)
            {
                if (DEBUG)
                {
                    System.Diagnostics.Debug.WriteLine("# Já estava conectado. Desconectando primeiro.");
                }

                desconectar();
            }

            if (DEBUG)
            {
                System.Diagnostics.Debug.WriteLine("# IP: " + Ip + " Porta: " + Porta);
            }

            IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(Ip), Porta);
            TcpClient = new TcpClient();
            try
            {
                TcpClient.Connect(ipEndPoint);
            }
            catch (Exception e)
            {
                if (DEBUG)
                {
                    System.Diagnostics.Debug.WriteLine(">>>" + e.Message);
                }
                return false;
            }

            if (DEBUG)
            {
                System.Diagnostics.Debug.WriteLine("# Conectado com sucesso!");
            }

            NetworkStream = TcpClient.GetStream();
            BinaryWriter = new BinaryWriter(NetworkStream);
            BinaryReader = new BinaryReader(NetworkStream);

            Conectado = true;

            return true;
        }

        public override void desconectar()
        {
            if (DEBUG)
            {
                System.Diagnostics.Debug.WriteLine("# Desconectado!");
            }

            BinaryReader.Close();
            BinaryWriter.Close();
            NetworkStream.Close();
            TcpClient.Close();

            Conectado = false;
        }

        public override void enviarMensagem(string mensagem)
        {
            if (Conectado)
            {
                if (DEBUG)
                {
                    System.Diagnostics.Debug.WriteLine("# Enviando mensagem: '" + mensagem + "'");
                }
                BinaryWriter.Write(mensagem);
            }
        }

        public void enviarMensagem(Mensagem mensagem)
        {
            if (Conectado)
            {
                if (DEBUG)
                {
                    System.Diagnostics.Debug.WriteLine("# Enviando mensagem: '" + mensagem + "'");
                }
                BinaryWriter.Write(mensagem.ObjectToByteArray());

                IFormatter formatter = new BinaryFormatter(); // the formatter that will serialize my object on my stream 

                formatter.Serialize(NetworkStream, mensagem); // the serialization process 
            }
        }

        public override string receberMensagem()
        {
            string mensagem = "";
            if (Conectado)
            {
                if (NetworkStream.DataAvailable)
                {
                    mensagem = BinaryReader.ReadString();

                    if (DEBUG)
                    {
                        System.Diagnostics.Debug.WriteLine("# Mensagem recebida: '" + mensagem + "'");
                    }
                }
            }

            return mensagem;
        }

        public Mensagem receberMensagemCertificado()
        {
            Mensagem mensagem = null;
            if (Conectado)
            {
                if (NetworkStream.DataAvailable)
                {
                    IFormatter formatter = new BinaryFormatter();

                    mensagem = (Mensagem)formatter.Deserialize(NetworkStream);

                    if (DEBUG)
                    {
                        System.Diagnostics.Debug.WriteLine("# Mensagem recebida: '" + mensagem + "'");
                    }
                }
            }

            return mensagem;
        }
    }
}
